package multi_thread.master.executors;

import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author Cheng Jun
 * Description: 该线程池支持定时，以及周期性的任务执行，我们可以延迟任务的执行时间，
 * 也可以设置一个周期性的时间让任务重复执行。 该线程池中有以下两种延迟的方法。
 * 推荐阅读博客：https://blog.csdn.net/l13591302862/article/details/112426574
 * 定时器线程池，试剂项目中很少使用，因为第三方组件 Quartz 功能更丰富、强大
 * @version 1.0
 * @date 2022/5/21 22:56
 * @see Executors#newScheduledThreadPool(int)
 */
public class Executor_ScheduledThreadPool {

    public static void main(String[] args) {
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
        Runnable scheduledTask = () -> {
            try {
                System.out.println("scheduledTask 开始运行，开始时间 " + LocalDateTime.now());
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("scheduledTask 结束运行，结束时间 " + LocalDateTime.now());
        };
        // scheduledTask 在5秒以后才会运行
        // scheduledThreadPool.schedule(scheduledTask, 5, TimeUnit.SECONDS);

        // scheduledTask 在延迟两秒以后，第一次运行 scheduledTask，
        // 运行完 scheduledTask后，等待固定的延迟时间——4秒，scheduledTask再次运行
        // scheduledThreadPool.scheduleWithFixedDelay(scheduledTask, 2, 4, TimeUnit.SECONDS);

        // scheduledTask 在延迟两秒以后，第一次运行 scheduledTask，scheduledTask总共运行时间记为 taskTime
        // 运行完 scheduledTask后，如果 period 大于 taskTime，那么在等待 period - taskTime 时间后，scheduledTask再次运行
        // 如果 period 小于等于 taskTime，那么 scheduledTask会立即再次运行
        scheduledThreadPool.scheduleAtFixedRate(scheduledTask, 2, 1, TimeUnit.SECONDS);

        // scheduledThreadPool.shutdown();
    }
}
